﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Xts
{
    namespace Util
    {
        public class XThreadSafeDictionary<T, U> : IDisposable
        {
            protected Dictionary<T, U> x_dict;
            protected Object x_lockObj;
            protected short x_waitingReaders;

            public XThreadSafeDictionary()
            {
                x_lockObj = new Object();
                x_dict = new Dictionary<T, U>();
                x_waitingReaders = 0;
            }

            #region Dispose Resources
            public void Dispose()
            {
                Dispose(true);
                //take us off of the finalization queue
                GC.SuppressFinalize(this);
            }

            protected virtual void Dispose(bool disposing)
            {
                if (!this.disposed)
                {
                    if (disposing)
                    {
                        //dispose of managed resources......
                        x_dict.Clear();
                    }
                    //dispose of unmanaged resources......
                    disposed = true;
                }
            }

            ~XThreadSafeDictionary() { Dispose(false); }

            private bool disposed = false;
            #endregion

            public bool Insert(T key, U val)
            {
                lock (x_lockObj)
                {
                    if (!x_dict.ContainsKey(key))
                    {
                        x_dict.Add(key, val);
                        return true;
                    }

                }
                return false;
            }

            public bool Delete(T key)
            {
                lock (x_lockObj)
                {
                    if (x_dict.ContainsKey(key))
                    {
                        x_dict.Remove(key);
                        return true;
                    }

                }
                return false;
            }

            public bool ContainsKey(T key)
            {
                lock (x_lockObj)
                {
                    if (x_dict.ContainsKey(key))
                    {
                        return true;
                    }
                }
                return false;
            }

            public bool GetItem(T key, out U val)
            {
                lock (x_lockObj)
                {
                    if (x_dict.ContainsKey(key))
                    {
                        val = x_dict[key];
                        return true;
                    }
                }
                val = default(U);
                return false;
            }

            public void SetItem(T key, U val)
            {
                lock (x_lockObj)
                {
                    x_dict[key] = val;
                }
            }

            public T[] Keys()
            {
                lock (x_lockObj)
                {
                    T[] keyArray = new T[x_dict.Count];
                    x_dict.Keys.CopyTo(keyArray, 0);
                    return keyArray;
                }
            }

            public U[] Values()
            {
                lock (x_lockObj)
                {
                    U[] valArray = new U[x_dict.Count];
                    x_dict.Values.CopyTo(valArray, 0);
                    return valArray;
                }
            }
        }


    }
}
